package com.gk.controller;

import com.alibaba.druid.util.StringUtils;
import com.github.houbb.segment.support.segment.result.impl.SegmentResultHandlers;
import com.github.houbb.segment.support.segment.result.impl.SegmentResultWordHandler;
import com.github.houbb.segment.util.SegmentHelper;
import com.gk.entity.Poem;
import com.gk.service.PoemService;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/poem")
@Api(tags = "检索系统后台 诗词信息管理模块")
public class PoemController {

    private static final Logger log = LoggerFactory.getLogger(PoemController.class);
    @Autowired
    private PoemService poemService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 分页查询诗词的所有信息
     * @param page 当前页
     * @param size 每页展示的记录数
     * @return
     */
    @ApiOperation("分页查询诗词信息接口")
    @RequestMapping(value = "/findByPage", method = RequestMethod.POST)
    @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "查询的页码", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "size", value = "每页显示条数", paramType = "query", dataType = "String")})
    public Map<String, Object> findByPage(@RequestParam("page") Integer page, @RequestParam("rows") Integer size) { //jqGrid插件的问题，提交过来的每页展示数是rows，所以这里一定要用rows接收
        //知识点@RequestBody是把请求的内容里的内容都读出来,正常接收的参数是一个对象。所以这里用@RequestParam
        Map<String, Object> map = new HashMap<>();

        //查询出当前页的所有记录
        List<Poem> poemList = poemService.findByPage(page, size);

        //查询出所有的记录数
        Integer totalCounts = poemService.findTotalCounts();

        //计算总页数
        long totalPages = totalCounts % size == 0 ? totalCounts / size : totalCounts / size + 1;

        //封装返回结果
        map.put("page", page);
        map.put("rows", poemList);
        map.put("total", totalPages);
        map.put("records", totalCounts);

        return map;
    }

    /**
     * 批量将数据库中数据 录入 ES索引库
     * @return
     */
    @RequestMapping(value = "/saveAll", method = RequestMethod.GET)
    public Map<String, Object> saveAll() {
        log.info("正在执行索引的创建请稍后....");
        Map<String, Object> map = new HashMap<>();

        try {
            poemService.saveAll();
            map.put("success", true);
            map.put("msg", "索引录入ES库成功");
        } catch (Exception e) {
            map.put("success", false);
            map.put("msg", "索引录入ES库失败：" + e.getMessage());
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 清空Es库中的所有文档
     * @return
     */
    @RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
    public Map<String, Object> deleteAll() {
        log.info("正在执行索引的清空....");
        Map<String, Object> map = new HashMap<>();

        try {
            poemService.deleteAll();
            map.put("success", true);
            map.put("msg", "清空文档成功！！！");
        } catch (Exception e) {
            map.put("success", false);
            map.put("msg", "清空文档失败：" + e.getMessage());
            e.printStackTrace();
        }
        return map;
    }

    @ApiOperation("前台系统根据关键词检索接口")
    @RequestMapping(value = "/findAllKeywords", method = RequestMethod.GET)
    @ApiImplicitParams({@ApiImplicitParam(name = "content", value = "搜索框内容", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "诗词类型", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "author", value = "作者", paramType = "query", dataType = "String")})
    public Map<String, Object> findAllKeywords(@RequestParam(required=false) String content, @RequestParam(required=false) String type, @RequestParam(required=false) String author) {

        Map<String, Object> map = new HashMap<>();

        //将搜索框内容分词，放入Redis
        if (!StringUtils.isEmpty(content)) {
            //对搜索结果进行分词处理
            List<String> segment = SegmentHelper.segment(content, SegmentResultHandlers.word());
            log.info("当前分词结果为：[{}]", segment);

            segment.forEach(word -> {
                if (word.length() > 1) {
                    stringRedisTemplate.opsForZSet().incrementScore("keywords", word, 0.5);
                }
            });
        }

        if (StringUtils.equals("所有", type)) type = null;
        if (StringUtils.equals("所有", author)) author = null;
        log.info("type:[{}] author:[{}] ", type, author);

        try {
            List<Poem> poems = poemService.findByKeywords(content, type, author);
            map.put("success", true);
            map.put("msg", "检索成功！！！");
            map.put("poems", poems);
        } catch (IOException e) {
            map.put("success", false);
            map.put("msg", "检索失败：" + e.getMessage());
        }

        return map;
    }

    @ApiOperation("获取Redis热词排行")
    @RequestMapping(value = "findRedisKeywords", method = RequestMethod.POST)
    public Set<ZSetOperations.TypedTuple<String>> findRedisKeywords() {
        Set<ZSetOperations.TypedTuple<String>> keywords = stringRedisTemplate.opsForZSet().reverseRangeWithScores("keywords", 0, 20);
        return keywords;
    }
}
